/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module Settle2.c - Settlement functionality |
   @end

$Log: /SoftPay/SPK2SIM/Source/Tran/settle2.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>

#ifdef BATCH_DEFINED

#define VSSETL2_C

#include <message.h>
#include <applidl.h>
#include <aclconio.h>
#include <acldev.h>
#include <aclstr.h>
#include <string.h>

/** /#define DEBUG_VSSETTLE*/
#ifdef DEBUG_VSSETTLE
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <settle.h>
#include <gds.h>
#include <tran.h>
#include <accum.h>
#include <date.h>
#include <ui.h>
#include <msg.h>
#include <mdlfuncs.h>
#include <msgfuncs.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <udt.h>
#include <tblutil.h>
#include <mht.h>
#include <bdt.h>
#include <hdt.h>
#include <lct.h>
#include <sdt.h>
#include <tct.h>
#include <cst.h>
#include <cdt.h>
#include <print.h>
#include <init.h>
#include <oper.h>
#include <modem.h>
#include <modemmsg.h>
#include <spdebug.h>
#include <protocol.h>
#include <confio.h>
#include <report.h>
#include <amount.h>
#include <operate.h>
#include <pbatch.h>
#include <settlbat.h>
#include <pfr.h>
#include <codesec.h>
#include <multilng.h>
#include <mem.h>
#include <logo.h>
#include <pcounter.h>
#include <funcs.h>

/*********************************************************************************************
* @func int | inResetBatch |
*
*               This function will delete the batch file for the
*                present host (Host type should be loaded in the GDS).
*                It also increments the batch number for that host and saves
*                in the HDT.
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inResetBatch(TRANSACTION_OBJECT* pobTran) {
    long lnBatchNum;
    int inBatchNumSize;

    /** /pdebug(("--inResetBatch--"));*/

    /* Increment batch num & save value in BDT after settle
     * Reset the mustsettle flag, & save value in HDT
     * in case the batch is cleared after a failed settlement.
     * but only if you are not in demo mode
     */
    if (!fGetDemoMode()) {
        lnBatchNum = lnGetBatchNum();
        inBatchNumSize = inGetBatchNumSize();
        if (++lnBatchNum > lnMaxValue(inBatchNumSize))
            lnBatchNum = 1L;
        vdSetBatchNum(lnBatchNum);
        vdMustSettleHostFlags(VS_FALSE);
    }

    if (inSaveMHTRec(inGetBatchIndex()) != VS_SUCCESS)   /* Disk write */ {
        vdDisplayMessageFromFile(lnGGErrorMessage(), ERROR_MSG);
        return(VS_ERR);
    }

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inReprintSettlRep  |
*
*               Reprints Settlement Report.
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inReprintSettlRep(TRANSACTION_OBJECT* pobTran) {
    /** /pdebug(("--inReprintSettlRep--"));*/
    if (inPrintSettlementReport(pobTran, VS_TRUE, VS_TRUE, VS_TRUE) != VS_SUCCESS)
        return(VS_ERR);
    else
        return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inFakeSettle   |
*
*               Simulates a settlement operation by displaying communication messages
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inFakeSettle(TRANSACTION_OBJECT* pobTran) {
    char szSettleMsg[30];

    pause(30);
    vdDisplayMessageFromFile(CONNECTED_MSG21, STATUS_MSG);
    pause(50);
    vdDisplayMessageFromFile(TRANSMITTING_MSG21, STATUS_MSG);
    pause(50);
    vdDisplayMessageFromFile(RECEIVING_MSG21, STATUS_MSG);
    pause(50);


    /* Don't increment the batch # in Demo per Sharon because we only have
       one batch # that is shared by live and demo mode and some hosts
       may not be able to settle batches that are not contiguious.
       Incrementing of the batch # in demo has never been done in SoftPay
       until the last leg of SoftPay 2000 1.0 so we are going back to
       the standard.  MDM - 06/01/00
    */


    /* Set Success Message so it appears in Batch History */
    vdGetMessageFromFile(DEMO_SETTLE_SUCCESS_MSG, szSettleMsg);
    vdSGRespMsg(szSettleMsg);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inSettleAHost|
*
*               Calls the protocol functions to settle a specific host
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inSettleAHost(TRANSACTION_OBJECT* pobTran) {
    int inResult = VS_ERR;
    int inSaveHostHandle;
    char szDate[DATE_SIZE + 1],
    szTime[TIME_SIZE + 1];
    VS_BOOL fSettleSucceeded,
    fCommErr = VS_FALSE;

#ifdef  COUNTER_DEFINED
    COUNTER_OBJECT obCounter;
#endif  /* COUNTER_DEFINED */

    /**/pdebug(("--inSettleAHost--"));/**/

    /* Dont execute the following during PFR if power fails after this segment */
    if (vPFRSetPartFunc(__LINE__)) {
        memset(pobTran->szRespMsg, 0x00, RESP_MSG_SIZE);

        vdGetDate(szDate, MMDDYY);
        vdGetTime(szTime);
        strlcpy(pobTran->szSettTime, szTime, DATE_SIZE);
        strlcpy(pobTran->szSettDate, szDate, DATE_SIZE);

        inSaveHostHandle = inGetHostHandle();
        /*
             *      Open Batch for Settlement here, where we are sure proper host has already
             *      been loaded.
             */
        vdBatchDCOpen(pobTran);
        if ((fGetDemoMode() == VS_TRUE) && (fGetTrainSettle() == VS_TRUE))
            inResult = inFakeSettle(pobTran);
        else {
#ifdef COUNTER_DEFINED
            inSetTimerOnOff(START_TIMER_3);
#endif  /* COUNTER_DEFINED */

            // This is a flow function and can be put in Settlement flow
            // and removed from here once settlement gets broken up
            if (inValidateDockStatus(pobTran) != VS_SUCCESS)
                return(VS_ERR);

            inResult = inRunSettleProtocolFunction(pobTran);

#ifdef COUNTER_DEFINED
            obCounter.inType = BATCH_SET_RESP_TIME;
            obCounter.inIndex = inGetCounterIndex();
            inIncCounter(&obCounter, (int) (inSetTimerOnOff(STOP_TIMER_3)));
#endif  /* COUNTER_DEFINED */
        }


        if (inResult == VS_SUCCESS) {
            //     BT_TRACE ('I', "Settle Successful");
            vdDisplayMessageFromFile(SETTLE_SUCCESS_MSG, STATUS_MSG);
            fSettleSucceeded = VS_TRUE;
            vdSGErrorMessage(0L);
            /* vdSGErrorMessage(EMPTY_STR_ERR_MSG);*/
        } else {
            pdebug(("inPackUnpack=%d", inResult));
            /*
                     *      Settle Error Handling
                     *          Do not overwrite error set in host code
                     *          Always display SETTLE FAILED ERROR MESSAGE
                     */
            if (strlen(pobTran->szRespMsg) > 0) {
                //             BT_TRACE ('I', pobTran->szRespMsg);
            } else {
                //           BT_TRACE ('I', "Settle Failed");
            }

            if (lnGGErrorMessage() == TXMT_FAIL_ERR_MSG)
                fCommErr = VS_TRUE;

            if (!fGGAutoSettle()) /* removed single settle check */ {

                vdDisplayMessageFromFile(SETTLE_FAIL_ERR_MSG, WARNING_MSG);
                SVC_WAIT(1000);
            }

            if (strlen(pobTran->szRespMsg) > 0)
                pad(pobTran->szRespMsg, pobTran->szRespMsg, ' ', MESSAGE_SIZE, CENTER);
            fSettleSucceeded = VS_FALSE;
        }

        /* In case the HDT record was changd during host settlement reset the HDT Table */

        if (inLoadHostData(inSaveHostHandle) != VS_SUCCESS)
            return(VS_ERR);

        inMakeTerminalTotals(pobTran, VS_FALSE, fSettleSucceeded);
        /** /pdebug(("fSettleSucceeded = %d", fSettleSucceeded));*/
    }// if (vPFRSetPartFunc(__LINE__)
    else {
        /* Because we have just recovered, the batch is set as OPEN in trans object */
        pobTran->fBatchOpen = VS_FALSE;
        vdBatchDCOpen(pobTran);
        fSettleSucceeded = VS_TRUE;
        /* Need to retrieve local variable to indicate settlement succeeded */
        inGetExternalPfrData(PFR_SETTLE_SUCCEED, (unsigned char *) &fSettleSucceeded, sizeof(VS_BOOL));
        // Set PFR_RECOVERING off so that the next host that comes through here
        // from pSettleAllHosts() will actually settle - AM55620/PE 564
        PFR_RECOVERING = 0;
    }


    /* Need to store local variable to indicate settlement succeeded */
    inAddExternalPfrData(PFR_SETTLE_SUCCEED, (unsigned char *) &fSettleSucceeded, sizeof(VS_BOOL));

    /* If we fail at this point, then the above segment will be skipped */
    inPFRStateStoreAll(PFR_BEGIN_SETTLE_REPORT, pobTran, 1, 1);

    pobTran->fSettleSucceeded = fSettleSucceeded;  // need for host code

    inPrintSettlementReport(pobTran, VS_FALSE, fSettleSucceeded, fCommErr);

    if (fSettleSucceeded) {
        SETT_REC srLocSRec;
        SETT_KEY srLocSKey;

        /* pj1 Add host name to sett_rec and set GDS*/
        strcpy(srRcpt.szHostName, szGetHostName());
        strcpy(srLocSRec.szHostName, srRcpt.szHostName);
        inPutSettRec(pobTran, &srLocSRec, &srLocSKey);

        /* if auto settlement do not show messages */
        if (fGGAutoSettle())
            inPurgeHostFromBatch(pobTran, inGetBatchIndex(), VS_FALSE);
        else
            inPurgeHostFromBatch(pobTran, inGetBatchIndex(), VS_TRUE);
        /* Delete open tab batch, formally done in inCheckOpenTabs() */
        if (inDeleteOpenTabBatch(pobTran) != VS_SUCCESS)
            vdDisplayMessageFromFile(SUSPEND_ERROR_MSG, ERROR_MSG);

        /* Reset Offline count after settlement */
        if ((inResult = inResetOfflineCount()) != VS_SUCCESS)
            vdDisplayMessageFromFile(BDT_ERR_MSG, ERROR_MSG);

        if ((inResult = inResetAccum()) != VS_SUCCESS)
            vdDisplayMessageFromFile(ACCUM_ERR_MSG, ERROR_MSG);

#ifdef CLERK_DEFINED
        if ((inResult = inResetUTT(pobTran)) != VS_SUCCESS)
            vdDisplayMessageFromFile(UTT_FAIL_ERR_MSG21, ERROR_MSG);

        /* reset active clerk file bb1 */
        if ((inResult = inResetADT()) != VS_SUCCESS)
            vdDisplayMessageFromFile(ADT_FILE_ERR_MSG21, ERROR_MSG);

        inResetUDTLogedIn();
#endif /* if CLERK_DEFINED */

        /* Zero the STT File */
#ifdef SHIFT_DEFINED
        if (inResetSTT(pobTran) != VS_SUCCESS)
            vdDisplayMessageFromFile(STT_FAIL_ERR_MSG21, ERROR_MSG);
#endif
    }

    /*
     *      Must close the batch so that if this function is called again for a different host the correct
     *      batch will be opened above.
     */
    vdCloseDCBatch(pobTran);
    vdFree((char *) pobTran->srBRec.pchHostData);
    pobTran->srBRec.pchHostData = NULL;

    return(inResult);
} /* End of inSettleAHost () */
/*********************************************************************************************
* @func int | pSettleAllHosts|
*
*               Uses the total number of records in the HDT table
*               and a for loop to settle each host
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int pSettleAllHosts(TRANSACTION_OBJECT* pobTran) {
    int inCnt,
    inResult,
    inResultSum = 0;
    char szDummy[MESSAGE_SIZE + 1];
    char szHostName[HOST_NAME_SIZE + 1];
    int inHosts;

    /**/pdebug(("--pSettleAllHosts--"));/**/
    inHosts = MAX_HOSTS;
    /* Add 1 to loop counter for loyalty settle */

    for (inCnt = 0; inCnt < inHosts; inCnt++) {
        pdebug(("inCnt=%d", inCnt));

        if (!fIsIndependentBatch(inCnt))
            continue;

        vdDisplayMessageFromFile(SETTLE_HOST_MSG, STATUS_MSG);
        vdGetMessageFromFile(SETTLE_HOST_MSG, szDummy);

        vdSetHostHandle(inCnt);

        if ((inResult = inLoadDefaultHost(inCnt)) != VS_SUCCESS) {
            pdebug(("inLoadDefaultHost=%d", inResult));
            return(inResult);
        }

        if ((inResult = inLoadDefaultCurrency(pobTran)) != VS_SUCCESS) {
            pdebug(("inLoadDefaultCurrency=%d", inResult));
            return(inResult);
        }

        strcpy(szHostName, szGetHostName());

        strcat(szDummy, szHostName);
        if ((get_font_mode() == 2) && (getgrid() == 0)) {
            char szTemp[10];
            char* ptr = strchr(szDummy, '-');

            strncpy(szTemp, szDummy, ptr - szDummy);
            vdDisplayAt(obDisp.inHomeCol, obDisp.inStatusLine, szTemp, CLR_EOL);
            inMLDisplayAt(strlen(szTemp), obDisp.inStatusLine, ptr, CLR_EOL, ML_USE_GIVEN_FONT, ML_MENU_FONT, ASC4X16_VFT);
        } else
            vdDisplayStatusString(szDummy);
        vdDelay(PROMPT_DELAY);

        vdSGCode(SETTLE); {
            long lnResult;

            lnResult = lnProceedWithSettlement(pobTran);
            if (lnResult == (long) VS_SUCCESS) {
                SVC_WAIT(2000);
                if (inSettleAHost(pobTran) != VS_SUCCESS)
                    inResultSum++;
                /* Reset the Power failure state */
                inPFRStateStoreAll(PFR_BEGIN_SETTLEMENT, pobTran, 1, 1);
            } else if (lnResult == BATCH_EMPTY_MSG) {
                vdDisplayMessageFromFile(SKIP_MSG, WARNING_MSG);
                inClrBatch(pobTran, CLEAR_HOST, VS_FALSE);
            }
        }
        vdCloseDCBatch(pobTran);
    }

    if (inResultSum > 0) {
        if ((fGGAutoSettle()) || (inResultSum == inHosts)) // auto settle or all hosts failed
            return(VS_ERR);
        else
            return(VS_FAILURE); /* not all host failed, but at least one did */
    }

    /* Reset invoice number after settlement, if all hosts settled successfully */
    if ((inResult = inResetInvNum()) != VS_SUCCESS)
        vdDisplayMessageFromFile(BDT_ERR_MSG, ERROR_MSG);

    return(VS_SUCCESS); /* all host settled successfully */
}

int SETTLE2_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

#undef VSSETL2_C

#endif // BATCH_DEFINED
